package com.atguigu.springcloud.controller;

import com.atguigu.springcloud.entities.Address;
import com.atguigu.springcloud.entities.Dept;
import com.atguigu.springcloud.service.DeptService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.*;

import java.security.Principal;
import java.util.List;

@RestController
@RequestMapping("/dept")
@Slf4j
public class DeptController {

    private DeptService deptService;
    private DiscoveryClient discoveryClient;

    @Autowired
    public DeptController(DeptService deptService, DiscoveryClient discoveryClient) {
        this.deptService = deptService;
        this.discoveryClient = discoveryClient;
    }

    /**
     * 服务端GET请求，没有入参
     *
     * @return 所有部门信息
     */
    @RequestMapping(value = "/list", method = RequestMethod.GET)
    public List<Dept> list() {
        return deptService.findAll();
    }

    /**
     * 服务端使用GET请求，且入参是从路径上取值
     *
     * @param id 部门id
     * @return 部门信息
     */
    @RequestMapping(value = "/get/{id}", method = RequestMethod.GET)
    public Dept get(@PathVariable("id") Long id) {
        return deptService.findById(id);
    }

    /**
     * 服务端GET请求，只有一个String类型的入参
     *
     * @param id 部门id
     * @return 部门信息
     */
    @RequestMapping(value = "/getById", method = RequestMethod.GET)
    public Dept getById(@RequestParam(value = "id") Long id) {
        return deptService.findById(id);
    }

    /**
     * 服务端GET请求，有一个以上的String类型入参
     *
     * @param id       部门id
     * @param deptName 部门名称
     * @return 部门信息
     */
    @RequestMapping(value = "/getByIdAndDeptName", method = RequestMethod.GET)
    public Dept getByIdAndDeptName(@RequestParam(value = "id") Long id,
                                   @RequestParam(value = "deptName") String deptName) {
        System.out.println("部门名称：" + deptName);
        return deptService.findById(id);
    }

    /**
     * 服务端使用GET请求，且入参是一个实体类
     *
     * @param dept 部门信息
     * @return 部门信息
     */
    @RequestMapping(value = "/getByDept", method = RequestMethod.GET)
    public Dept getByDept(Dept dept) {
        return deptService.findById(dept.getDeptno());
    }

    /**
     * 服务器使用POST请求，入参是一个实体类
     *
     * @param dept 部门信息
     * @return 是否添加成功
     */
    @RequestMapping(value = "/add", method = RequestMethod.POST)
    public boolean add(@RequestBody Dept dept) {
        return deptService.addDept(dept);
    }

    /**
     * 服务器使用POST请求，入参是两个实体类
     * (服务器端的这种接口，在客户端没法通过feign进行调用)
     * 【因为在POST请求方式下，feign不支持传递两个实体对象】 但是服务端自身可以直接调用
     *
     * @param principal  登录信息
     * @param dept       部门信息
     * @return           是否添加成功
     */
    @RequestMapping(value = "/addWithAddress0", method = RequestMethod.POST)
    public boolean addWithAddress0(Principal principal,
                                   @RequestBody Dept dept) {
        if (principal == null) {
            System.out.println("没登录...");
        } else {
            System.out.println(principal.getName() + "...");
        }
        return deptService.addDept(dept);
    }

    /**
     *
     * 由于上面的那种接口不支持客户端通过feign进行调用，所以修改称下面这样
     * 服务器使用POST请求，入参是一个字符串和一个实体类
     *
     * @param username  用户名
     * @param dept      部门信息
     * @return          是否添加成功
     */
    @RequestMapping(value = "/addWithAddress1", method = RequestMethod.POST)
    public boolean addWithAddress(@RequestParam String username,
                                  @RequestBody Dept dept) {
        System.out.println("username:" + username);
        return deptService.addDept(dept);
    }

    /**
     *
     * @param address
     * @param dept
     * @return
     */
    @RequestMapping(value = "/addWithAddress2", method = RequestMethod.POST)
    public boolean addWithAddress2(Address address,
                                   Dept dept) {
        System.out.println("address:" + address);
        return deptService.addDept(dept);
    }

    // Eureka的服务发现方法，这个接口提供给调用者，调用者调用这个接口可以查询(发现)这个微服务的信息（比如这个微服务的访问地址信息）
    @RequestMapping(value = "/discovery", method = RequestMethod.GET)
    public Object discovery() {
        List<String> servicesList = discoveryClient.getServices();
        log.info("服务列表：" + servicesList);
        List<ServiceInstance> deptInstances = discoveryClient.getInstances("MICROSERVICECLOUD-DEPT");
        for (ServiceInstance deptInstance : deptInstances) {
            log.info(deptInstance.getServiceId() + "\t" + deptInstance.getHost() + "\t" + deptInstance.getPort() + "\t" + deptInstance.getUri());
        }
        return this.discoveryClient;
    }

}
